feat: add find command for catalog search#174
feat: add find command for catalog search#174nadavs123 wants to merge 29 commits intomicrosoft:mainfrom
find command for catalog search#174Conversation
Features: - Search across all workspaces by displayName, workspaceName, or description - Filter by item type with --type flag - Limit results with --limit flag - Detailed output with --detailed flag (includes id, workspaceId) - Custom endpoint support with --endpoint flag or FAB_CATALOG_ENDPOINT env var Output columns (default): name, type, workspace, description Output columns (detailed): + workspaceId, id Required scope: Catalog.Read.All Unsupported types: Dashboard, Dataflow, Scorecard Includes unit tests (12 tests passing)
…dling Changes based on issue microsoft#172 feedback: - Changed --type from comma-separated to nargs='+' (space-separated) - Removed --endpoint flag (use internal mechanism instead) - Added FabricCLIError for invalid/unsupported item types - Added error handling for API failures - Updated tests to match new patterns (15 tests passing)
- Added complete_item_types() completer for searchable types - Tab completion excludes unsupported types (Dashboard, Dataflow, Scorecard) - Restored unsupported type validation with clear error message - Updated ALL_ITEM_TYPES list from official API spec - Added SEARCHABLE_ITEM_TYPES for valid filter types - 20 tests passing
- Keep tab-completion for --type flag - Custom FabricCLIError for unsupported types (Dashboard, Dataflow, Scorecard) - Custom FabricCLIError for unknown types - Cleaner error messages vs argparse choices listing all 40+ types - 22 tests passing
- Changed from data= to json= for request payload - Added raw_response=True to avoid auto-pagination hanging - Added fallback from displayName to name (API bug workaround) - Updated tests to use dict instead of JSON string - Successfully tested against dailyapi.fabric.microsoft.com
…, workspace_id, description)
…ination and -P params - Interactive mode: pages 50 items at a time with 'Press any key to continue...' - Command-line mode: fetches up to 1000 items in a single request - Replace --type with -P type=Report,Lakehouse (key=value pattern) - Remove --max-items and --next-token flags Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The Catalog Search API returns an empty string continuationToken on the last page instead of null/omitting it. This caused the interactive pagination loop to send an empty token on the next request, which the API treats as a fresh empty search — returning unrelated results from the entire tenant. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Long descriptions caused the table separator line to wrap, appearing as a double separator. Descriptions are now truncated with ellipsis to keep the table within the terminal width. Full descriptions are still available via -l/--long mode. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Command-line mode now fetches all pages instead of stopping at one page of 1000. Uses the same continuation token pattern as interactive mode with 'or None' guard against empty string tokens. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Use contractions and active voice for friendlier tone - Suggest close matches for unknown types instead of dumping all 43 - Remove redundant type list from unsupported type error Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
|
||
|
|
||
| # All Fabric item types (from API spec, alphabetically sorted) | ||
| ALL_ITEM_TYPES = [ |
There was a problem hiding this comment.
Can't we have those types from an API and save it on init?
If not, please move it to separate file, maybe fab_constant or create type_supported.yaml - same as we have command_supported.
| ] | ||
|
|
||
| # Types that ARE searchable (for validation) | ||
| SEARCHABLE_ITEM_TYPES = [t for t in ALL_ITEM_TYPES if t not in UNSUPPORTED_ITEM_TYPES] |
There was a problem hiding this comment.
why not having supported and unsupported type list?
| if args.query: | ||
| args.query = utils.process_nargs(args.query) | ||
|
|
||
| is_interactive = getattr(args, "fab_mode", None) == fab_constant.FAB_MODE_INTERACTIVE |
There was a problem hiding this comment.
The current fab_mode check does not always indicate that the CLI is running in interactive mode. When the user runs fab and presses Enter, the CLI enters interactive mode even if the configuration mode is set to command_line. You may want to pass this explicitly to the command as a parameter.
| from fabric_cli.client.fab_api_types import ApiResponse | ||
|
|
||
|
|
||
| def catalog_search(args: Namespace, payload: dict) -> ApiResponse: |
There was a problem hiding this comment.
nit - since we are in catalog_api consider rename to search(args: Namespace, payload: dict)
|
|
||
| def _raise_on_error(response) -> None: | ||
| """Raise FabricCLIError if the API response indicates failure.""" | ||
| if response.status_code != 200: |
There was a problem hiding this comment.
are we getting to this point?
since do_request() handle cases where status is not 200 and throw an error that is catch by handle_exceptions decorator
| required=False, | ||
| metavar="", | ||
| nargs="*", | ||
| help="Parameters in key=value or key!=value format. Use brackets for multiple values: type=[Lakehouse,Notebook]. Use != to exclude: type!=Dashboard", |
There was a problem hiding this comment.
If you parse it with get_dict_from_params, I think you will need to use quats: type=["Lakehouse","Notebook"]
| "-l", | ||
| "--long", | ||
| action="store_true", | ||
| help="Show detailed output. Optional", |
issue-172.md
Outdated
| @@ -0,0 +1,312 @@ | |||
| ### Use Case / Problem | |||
There was a problem hiding this comment.
what is this file?
should be removed?
There was a problem hiding this comment.
Sorry it's just the draft of the issue itself. I'll remove it.
| @@ -0,0 +1,2 @@ | |||
| # Copyright (c) Microsoft Corporation. | |||
There was a problem hiding this comment.
remove and place the test_find directly under test_command
| assert payload["filter"] == "(Type ne 'Dashboard' and Type ne 'Datamart')" | ||
|
|
||
|
|
||
| class TestParseTypeParam: |
There was a problem hiding this comment.
you should create e2e tests that call find command and record the tests and validate all different scenarios instead of those unit tests.
|
Please update the description: fab find "monthly" --type Report Warehouse - should be list fab find "dashboard" --max-items 10 - flag doesnt exist fab find --next-token "eyJTa2lwIjoy..." - flag doesnt exist |
| @@ -0,0 +1,2 @@ | |||
| # Copyright (c) Microsoft Corporation. | |||
There was a problem hiding this comment.
Please add documentation for this new command - under docs folder.
here you can find the guidelines how to rebuild it locally
This is just a draft of the issue I opened
📥 Pull Request
Closes #172
Summary
Adds a new
findcommand that searches for Fabric items across all accessible workspaces using the Catalog Search API (POST /v1/catalog/search).Usage
Flags
--type--max-items-l/--long--next-tokenImplementation details
@fab_commanddecorator,print_output_format(),FabricCLIError--typeviaargcomplete--max-itemsvalidation (1-1000)-l) mode--next-token(continuation token approach)Files added
src/fabric_cli/client/fab_api_catalog.py— API clientsrc/fabric_cli/commands/find/__init__.py— Package initsrc/fabric_cli/commands/find/fab_find.py— Command logicsrc/fabric_cli/parsers/fab_find_parser.py— Argument parsertests/test_commands/find/__init__.py— Test package inittests/test_commands/find/test_find.py— 22 unit tests.changes/unreleased/added-20260209-171617.yaml— Changie entryFiles modified
src/fabric_cli/core/fab_parser_setup.py— Register find parserNotes
Dataflow)ReportCatalog.Read.Allscope (not yet added to CLI app registration)